package il.ac.tau.dbcourse.test;

import il.ac.tau.dbcourse.db.Album;
import il.ac.tau.dbcourse.db.Artist;
import il.ac.tau.dbcourse.db.ConnectionFactory;
import il.ac.tau.dbcourse.db.DBException;
import il.ac.tau.dbcourse.db.Genre;
import il.ac.tau.dbcourse.db.PersistenceManager;
import il.ac.tau.dbcourse.db.Track;

import java.io.IOException;
import java.net.URL;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Properties;

public class PopUtils {
	private static String[] genre; 
	private static String[] names;
	private static Connection conn;
	static {
		try {
			conn=ConnectionFactory.getConnection();
		} catch (DBException e1) {
			e1.printStackTrace();
		}
		Properties props = new Properties();
		URL url = ClassLoader.getSystemResource("il/ac/tau/dbcourse/test/popData.properties");
		try {
			props.load(url.openStream());
			genre=props.getProperty("genres").split("\\|\\|");
			names=props.getProperty("names").split("\\|\\|");
			
		} catch (IOException e) {
			genre=new String[]{"Rock","Pop","Classic"};
			names=new String[]{"First artist","Second artist","Third artist"};
		}
		
	}

	private static HashMap<Long, Artist> artistHashmap = new HashMap<Long, Artist>();
	private static HashMap<Long, Album> albumHashmap = new HashMap<Long, Album>();
	private static HashMap<Long, Genre> genreHashmap = new HashMap<Long, Genre>();

	@SuppressWarnings("unchecked")
	private static <T> T getRandom(HashMap<Long, T> hashMap) {
		T[] array = (T[]) hashMap.values().toArray();

		int r = ((int) Math.round(Math.random() * array.length));
		if (r >= array.length)
			r = array.length - 1;
		return array[r];

	}
	
	private static String getName() {
		int r = (int) Math.round(Math.random() * names.length);
		if (names.length <= r)
			r = names.length - 1;
		return names[r];
	}

	private static String getGenreName() {
		int r = (int) Math.round(Math.random() * genre.length);
		if (genre.length <= r)
			r = genre.length - 1;
		return genre[r];
	}

	private static int getYear(){
		return ((int) Math.round(Math.random() * 30)) + 1979;
	}
	
	private static int getTrackLength(){
		return ((int) Math.round(Math.random() * 300)) + 90;
	}
	public static Genre getNewGenre(){
		String gName = getGenreName();
		Genre genre = new Genre(gName);
		Long id=PersistenceManager.save(conn, genre);
		genreHashmap.put(id,genre);
		return genre;
	}
	
	public static Artist getNewArtist(){
		Artist artist = new Artist();
		artist.setName(getName());
		Long id=PersistenceManager.save(conn,artist);
		artistHashmap.put(id,artist);
		return artist;
	}
	
	public static Album getNewAlbum(){
		return getNewAlbum(getRandom(artistHashmap));
	}
	public static Album getNewAlbum(Artist artist){
		Album album=new Album(artist);
		album.setTitle(getName());
		album.setGenre(getRandom(genreHashmap));
		album.setLength(10);
		album.setYear(getYear());
		Long id=PersistenceManager.save(conn,album);
		albumHashmap.put(id, album);
		return album;
	}
	
	
	public static Track getNewTrack(Album album, int trackNumber){
		Track track=new Track(album);
		track.setTitle(getName());
		track.setLength(getTrackLength());
		track.setTrackNumber(trackNumber);
		PersistenceManager.save(conn,track);
		return track;
	}
	public static ArrayList<Long> populateGenre(int count) {
		ArrayList<Long> ids = new ArrayList<Long>();

		for (int i = 0; i < count; i++) {
			
			Genre genre = getNewGenre();
			try {
				Long id = PersistenceManager.save(conn,genre);
				genreHashmap.put(id, genre);
				ids.add(id);
			} catch (Exception e) {
				e.printStackTrace();
			}

		}
		return ids;
	}

	public static ArrayList<Long> populateArtists(int count) {
		ArrayList<Long> ids = new ArrayList<Long>();

		for (int i = 0; i < count; i++) {
			Artist artist=getNewArtist();
			try {
				Long id = PersistenceManager.save(conn,artist);
				artistHashmap.put(id, artist);
				ids.add(id);
			} catch (Exception e) {
				System.out.println(artist.getName());
			}
		}

		return ids;
	}

	public static ArrayList<Long> populateAlbums(int count) {
		ArrayList<Long> ids = new ArrayList<Long>();
		for (int i = 0; i < count; i++) {
			Artist artist = getRandom(artistHashmap);
			ids.addAll(populateAlbums(1, artist));
		}
		return ids;
	}

	public static ArrayList<Long> populateAlbums(int count, Artist artist) {
		ArrayList<Long> ids = new ArrayList<Long>();
		for (int i = 0; i < count; i++) {
			
			Album album=getNewAlbum(artist);

			int trackCount = ((int) Math.round(Math.random() * 20)) + 5;
			System.out.println("Generating " + album.getTitle() + " with "
					+ trackCount + " tracks");
			Long id = PersistenceManager.save(conn,album);
			albumHashmap.put(id, album);
			populateTrack(trackCount, album);
			ids.add(id);

		}
		return ids;
	}

	public static ArrayList<Long> populateTrack(int count, Album album) {
		ArrayList<Long> ids = new ArrayList<Long>();
		for (int i = 0; i < count; i++) {
			Track track=getNewTrack(album, (i+1));
			ids.add(PersistenceManager.save(conn,track));
		}
		return ids;
	}

	public static void clearAllTracks(List<Long> ids) {
		for (Long id : ids) {
			PersistenceManager.delete(conn,Track.class, id);
		}
	}
	
	public static void clearAllArtists(List<Long> ids) {
		for (Long id : ids) {
			PersistenceManager.delete(conn,Artist.class, id);
			if (artistHashmap.containsKey(id)) artistHashmap.remove(id);
		}
	}

	public static void clearAllAlbums(List<Long> ids) {
		for (Long id : ids) {
			PersistenceManager.delete(conn,Album.class, id);
			if (albumHashmap.containsKey(id)) albumHashmap.remove(id);
		}
	}
	public static void clearAllGenres(List<Long> ids) {
		for (Long id : ids) {
			PersistenceManager.delete(conn,Genre.class, id);
			if (genreHashmap.containsKey(id)) genreHashmap.remove(id);
		}
	}

	public static void clearAll(){
		genreHashmap.clear();
		albumHashmap.clear();
		genreHashmap.clear();
		artistHashmap = new HashMap<Long, Artist>();
		albumHashmap = new HashMap<Long, Album>();
		genreHashmap = new HashMap<Long, Genre>();
		PersistenceManager.clearDB(conn);
		
	}
}
